package test_pkg

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
)

func Test_file_read() {
	// os 为操作系统功能提供了一个独立于平台的接口 旨在在所有操作系统中保持一致
	//如果文件不存在或者程序没有足够的权限打开这个文件，Open 函数会返回一个错误
	// file, err := os.Open("./test_pkg/test_fmt.go") //os.Open 读取的是项目根目录
	file, err := os.Open("products.txt") //os.Open 读取的是项目根目录

	if err != nil {
		fmt.Printf("An error occurred on opening the inputfile\n" +
			"Does the file exist?\n" +
			"Have you got acces to it?\n")
		return // exit the function on error
	}

	data := make([]byte, 100)
	//读取
	n, err := file.Read(data) //读取 len(data) 字节，并存储到 data 中
	if err != nil {
		fmt.Printf("读取失败 \n")
		return
	}

	//确保在程序退出前关闭该文件
	defer file.Close()

	// fmt.Printf("读取 %d 字节：%q\n", n, data)
	fmt.Printf("读取 %d 字节：%s\n", n, data)

	//读取全部
	// b, err2 := os.ReadFile("./test_pkg/test_fmt.go")
	// if err2 == nil {
	// 	fmt.Printf("读取全部: %s\n", b)
	// }

	//bufio 文本的读写包  bufio 包提供的读取器（写入器也类似），我们可以很方便的操作相对高层的 string 对象，而避免了去操作比较底层的字节
	// inputReader := bufio.NewReader(file)
	// for {
	// 	//读取全部
	// 	inputString, err := inputReader.ReadString('\n')
	// 	fmt.Printf("the input was: %s", inputString)
	// 	if err != nil {
	// 		return
	// 	}
	// }

	// 在很多情况下，文件的内容是不按行划分的，或者干脆就是一个二进制文件。
	// 在这种情况下，ReadString() 就无法使用了，我们可以使用 bufio.Reader 的 Read()

	inputFile := "products.txt"
	outputFile := "products_copy.txt"

	file1, _ := os.Open(inputFile)
	inputReader := bufio.NewReader(file1)
	buf := make([]byte, 1024)
	n2, err3 := inputReader.Read(buf)
	if err3 != nil {
		fmt.Printf("\"读取失败\": %v\n", "读取失败")
	}
	fmt.Printf("inputReader.Read: 读取字节数 %v, 内容: %s\n", n2, buf)

	// 将整个文件的内容读到一个字符串里  可以使用 io/ioutil 包(适用于文件比较小的读入)
	buff, err := ioutil.ReadFile(inputFile)
	if err != nil {
		fmt.Fprintf(os.Stderr, "File Error %s\n", err)
	}

	//写文件
	fmt.Printf("buff: %s\n", buff)
	err2 := ioutil.WriteFile(outputFile, buff, 0644)
	if err != nil {
		panic(err2.Error())
	}
}

func Test_read_line() {
	//按行读取
	file, err := os.Open("products.txt")
	if err != nil {
		panic(err)
	}
	defer file.Close()

	var col1, col2, col3 []string
	for {
		var v1, v2, v3 string
		_, err := fmt.Fscanln(file, &v1, &v2, &v3)
		// scans until newline
		if err != nil {
			break
		}
		col1 = append(col1, v1)
		col2 = append(col2, v2)
		col3 = append(col3, v3)
	}

	fmt.Println(col1)
	fmt.Println(col2)
	fmt.Println(col3)
}
